home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Popular Request
/
By Popular Request (Arsenal Computer)(SysOptics Distribution System).ISO
/
amiga4
/
sclk1_72.lha
/
SClock
/
Source
/
analog.c
next >
Wrap
C/C++ Source or Header
|
1993-12-26
|
10KB
|
464 lines
/****************************************************************************
*
* VERSION
* $VER: analog.c 1.66 (08.12.93)
*
* DESCRIPTION
* Analog clock display code...
*
* AUTHOR
* Rune Johnsrud
*
* COPYRIGHT
* (c) 1993 Amiga Freelancers
*
*****************************************************************************/
#include <graphics/gfxmacros.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <utility/date.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/diskfont.h>
#include <proto/gadtools.h>
#include <proto/layers.h>
#include "global.h"
/****************************************************************************/
extern struct GlobalData *gd;
extern struct ClockInfo *ci;
extern struct Gadget ClockGadget;
extern WORD SinTab[60];
extern WORD CosTab[60];
/****************************************************************************/
struct RectPoints
{
WORD x;
WORD y;
WORD w;
WORD h;
};
#define NUM_OF_VECTORS 100
#define MAXVECTORS NUM_OF_VECTORS / 5
#define MINTERM_VCOPY 0xC0
#define CB_COPY TRUE
#define CB_PASTE FALSE
#define DT_RENDER_BITMAP TRUE
#define DT_GET_ATTRS FALSE
#define DIV_SCALER 1024
/****************************************************************************/
static VOID CalcWinDims(VOID);
static WORD DrawClock(VOID);
static VOID DrawTimeI(WORD x, WORD y, UBYTE pen);
static VOID SortBlitPoints(WORD x, WORD y, WORD w, WORD h, struct RectPoints *p);
static VOID BlitClip(WORD x, WORD y, WORD ox, WORD oy, BOOL source);
static VOID SaveDisplay(VOID);
static VOID RestoreDisplay(VOID);
WORD CreateAnalogClock(VOID);
VOID RefreshAnalogClock(VOID);
WORD DeleteAnalogClock(VOID);
/****************************************************************************/
static VOID CalcWinDims(VOID)
{
if (ci->WinBevel)
{
ci->InnerTop = 1;
ci->InnerLeft = 1;
ci->InnerWidth = ci->Width - 1;
ci->InnerHeight = ci->Height - 1;
}
else
{
ci->InnerTop = 0;
ci->InnerLeft = 0;
ci->InnerWidth = ci->Width;
ci->InnerHeight = ci->Height;
}
if (ci->PlaceClock)
{
ci->ap.CtX = ((ci->ap.ClockLeft + ci->ap.ClockWidth) / 2);
ci->ap.CtY = ((ci->ap.ClockTop + ci->ap.ClockHeight) / 2);
ci->ap.SzX = (ci->ap.ClockWidth / 2);
ci->ap.SzY = (ci->ap.ClockHeight / 2);
if (ci->ap.SzX > (ci->Width / 2))
ci->ap.SzX = (ci->Width / 2);
if (ci->ap.SzY > (ci->Height / 2))
ci->ap.SzY = (ci->Height / 2);
if ((ci->ap.CtX + ci->ap.SzX) >= ci->Width)
ci->ap.CtX = (ci->Width - ci->ap.SzX) - 1;
if ((ci->ap.CtY + ci->ap.SzY) >= ci->Height)
ci->ap.CtY = (ci->Height - ci->ap.SzY) - 1;
}
else
{
ci->ap.CtX = (ci->InnerWidth / 2);
ci->ap.CtY = (ci->InnerHeight / 2);
ci->ap.SzX = (ci->ap.CtX - ci->EdgeSpace);
ci->ap.SzY = (ci->ap.CtY - ci->EdgeSpace);
}
ci->ap.SzX -= (ci->ap.SzX / ci->ap.MIXScale);
ci->ap.SzY -= (ci->ap.SzY / ci->ap.MIYScale);
if (ci->ShowDial)
{
ci->ap.SzX -= 2;
ci->ap.SzY -= 2;
}
ci->ap.Dec = ((ci->ap.SzX + ci->ap.SzY) / 5);
}
static WORD DrawClock(VOID)
{
struct RastPort *rp = gd->ClockWindow->RPort;
struct TmpRas tmpras;
struct AreaInfo areainfo;
VOID *rasdata = NULL;
WORD *vecbuff = NULL;
ULONG rsize;
WORD a, x, y, sx, sy, errcode = NOERROR;
sx = (ci->ap.SzX / ci->ap.MIXScale);
sy = (ci->ap.SzY / ci->ap.MIYScale);
if (ci->ShowDial)
{
rsize = RASSIZE(ci->Width, ci->Height);
rasdata = (VOID *) AllocVec(rsize, MEMF_CHIP);
vecbuff = (WORD *) AllocVec(NUM_OF_VECTORS, MEMF_CLEAR);
if (rasdata && vecbuff)
{
InitTmpRas(&tmpras, rasdata, rsize);
rp->TmpRas = &tmpras;
InitArea(&areainfo, vecbuff, MAXVECTORS);
rp->AreaInfo = &areainfo;
SetAPen(rp, ci->apn.DialOPen);
AreaEllipse(rp, ci->ap.CtX, ci->ap.CtY, 2 + ci->ap.SzX + sx, 2 + ci->ap.SzY + sy);
AreaEnd(rp);
SetAPen(rp, ci->apn.DialPen);
AreaEllipse(rp, ci->ap.CtX, ci->ap.CtY, 1 + ci->ap.SzX + sx, 1 + ci->ap.SzY + sy);
AreaEnd(rp);
}
else
errcode = GEN_ERR_ALLOCMEM;
if (rasdata)
{
FreeVec(rasdata);
rp->TmpRas = NULL;
}
if (vecbuff)
{
FreeVec(vecbuff);
rp->AreaInfo = NULL;
}
}
SetAPen(rp, ci->apn.MinSmallPen);
for (a=0; a<60; a++)
{
x = ci->ap.CtX + ((SinTab[a] * ci->ap.SzX) / DIV_SCALER);
y = ci->ap.CtY - ((CosTab[a] * ci->ap.SzY) / DIV_SCALER);
WritePixel(rp, x, y);
}
SetAPen(rp, ci->apn.MinLargePen);
for (a=0; a<60; a+=5)
{
x = ci->ap.CtX + ((SinTab[a] * ci->ap.SzX) / DIV_SCALER);
y = ci->ap.CtY - ((CosTab[a] * ci->ap.SzY) / DIV_SCALER);
RectFill(rp, x - sx, y - sy, x + sx, y + sy);
}
return errcode;
}
static VOID DrawTimeI(WORD x, WORD y, UBYTE pen)
{
struct RastPort *rp = gd->ClockWindow->RPort;
SetAPen(rp, pen);
Move(rp, ci->ap.CtX, ci->ap.CtY);
Draw(rp, x, y);
}
WORD CreateAnalogClock(VOID)
{
struct Gadget *g = &ClockGadget;
struct RastPort *rp;
UBYTE depth;
if (gd->ClockWindow) CleanUpClock();
// gd->TextFont = OpenDiskFont(&gd->TextAttr);
// if (!gd->TextFont) return GEN_ERR_OPENFONT;
gd->VScreen = LockPubScreen(ci->PubScreenName);
if (!gd->VScreen) return GEN_ERR_LOCKSCREEN;
gd->VisualInfo = GetVisualInfo(gd->VScreen, NULL);
if (!gd->VisualInfo) return GEN_ERR_GETVISUALINFO;
if ((ci->AutoSize) && (ci->BDRPic)) Error("Datatypes", ReadDTPic(DT_GET_ATTRS));
CalcWinDims();
gd->ClockWindow = OpenWindowTags(NULL,
WA_PubScreen, gd->VScreen,
WA_Top, ci->Top,
WA_Left, ci->Left,
WA_InnerWidth, ci->Width,
WA_InnerHeight, ci->Height,
WA_Activate, TRUE,
WA_Borderless, TRUE,
WA_Backdrop, ci->BDClock,
WA_DragBar, FALSE,
WA_NewLookMenus,TRUE,
WA_IDCMP, IDCMP_MENUPICK | IDCMP_IDCMPUPDATE,
TAG_DONE);
if (!gd->ClockWindow) return GEN_ERR_OPENWINDOW;
depth = GetBitMapAttr(gd->VScreen->RastPort.BitMap, BMA_DEPTH);
gd->SaveBM = AllocBitMap(ci->Width, ci->Height, depth, BMF_INTERLEAVED, NULL);
if (!gd->SaveBM) return GEN_ERR_ALLOCMEM;
InitRastPort(&gd->SaveRP);
gd->SaveRP.BitMap = gd->SaveBM;
if (!InitMainMenus()) return GEN_ERR_MENUS;
g->Width = ci->InnerWidth;
g->Height = ci->InnerHeight;
gd->ClockGadget = g;
rp = gd->ClockWindow->RPort;
// gd->FillRP = *rp;
// SetAPen(&gd->FillRP, ci->BGPen);
SetAPen(rp, ci->BGPen);
RectFill(rp, 0, 0, ci->InnerWidth, ci->InnerHeight);
if (ci->WinBevel)
{
SetAPen(rp, ci->ShinePen);
Move(rp, 0, ci->InnerHeight);
Draw(rp, 0, 0);
Draw(rp, ci->InnerWidth, 0);
SetAPen(rp, ci->ShadowPen);
Move(rp, ci->InnerWidth, 1);
Draw(rp, ci->InnerWidth, ci->InnerHeight);
Draw(rp, 0, ci->InnerHeight);
ci->InnerWidth--;
ci->InnerHeight--;
}
if (ci->BDRPic) Error("Datatypes", ReadDTPic(DT_RENDER_BITMAP));
if (gd->VScreen)
{
UnlockPubScreen(NULL, gd->VScreen);
gd->VScreen = NULL;
}
Error("Draw Clock", DrawClock());
// SetABPenDrMd(rp, ci->TextPen, ci->BGPen, JAM2);
// SetFont(rp, gd->TextFont);
AddGadget (gd->ClockWindow, gd->ClockGadget, -1);
RefreshGList(gd->ClockGadget, gd->ClockWindow, NULL, -1);
gd->CData.min = 99;
gd->CData.hour = 99;
GetCurrSysTime();
SaveDisplay();
RefreshAnalogClock();
return NOERROR;
}
static VOID SortBlitPoints(WORD x, WORD y, WORD w, WORD h, struct RectPoints *p)
{
if (x <= w)
{
p->x = x - 1;
p->w = w + 1;
}
else
{
p->x = w - 1;
p->w = x + 1;
}
if (y <= h)
{
p->y = y - 1;
p->h = h + 1;
}
else
{
p->y = h - 1;
p->h = y + 1;
}
}
static VOID BlitClip(WORD x, WORD y, WORD ox, WORD oy, BOOL source)
{
struct RectPoints p;
struct RastPort *rp = gd->ClockWindow->RPort;
SortBlitPoints(x, y, ci->ap.CtX, ci->ap.CtY, &p);
if (source)
{
ClipBlit(rp, p.x, p.y, &gd->SaveRP, ox, oy,
(p.w - p.x), (p.h - p.y), MINTERM_VCOPY);
}
else
{
ClipBlit(&gd->SaveRP, ox, oy, rp, p.x, p.y,
(p.w - p.x), (p.h - p.y), MINTERM_VCOPY);
}
}
static VOID SaveDisplay(VOID)
{
WORD i;
if (ci->ShowSec)
{
i = gd->CData.sec;
ci->ap.sx = ci->ap.CtX + ((SinTab[i] * ci->ap.SzX) / DIV_SCALER);
ci->ap.sy = ci->ap.CtY - ((CosTab[i] * ci->ap.SzY) / DIV_SCALER);
BlitClip(ci->ap.sx, ci->ap.sy, 0, 0, CB_COPY);
}
if (gd->NewMin)
{
i = gd->CData.min;
ci->ap.mx = ci->ap.CtX + ((SinTab[i] * ci->ap.SzX) / DIV_SCALER);
ci->ap.my = ci->ap.CtY - ((CosTab[i] * ci->ap.SzY) / DIV_SCALER);
BlitClip(ci->ap.mx, ci->ap.my, (ci->Width / 2), 0, CB_COPY);
gd->NewMin = FALSE;
}
if (gd->NewHour)
{
i = (((gd->CData.hour % 12) * 5) + (gd->CData.min / 12));
ci->ap.hx = ci->ap.CtX + ((SinTab[i] * (ci->ap.SzX - ci->ap.Dec)) / DIV_SCALER);
ci->ap.hy = ci->ap.CtY - ((CosTab[i] * (ci->ap.SzY - ci->ap.Dec)) / DIV_SCALER);
BlitClip(ci->ap.hx, ci->ap.hy, 0, (ci->Height / 2), CB_COPY);
gd->NewHour = FALSE;
}
}
static VOID RestoreDisplay(VOID)
{
if (ci->ShowSec)
BlitClip(ci->ap.sx, ci->ap.sy, 0, 0, CB_PASTE);
if (gd->NewMin)
BlitClip(ci->ap.mx, ci->ap.my, (ci->Width / 2), 0, CB_PASTE);
if (gd->NewHour)
BlitClip(ci->ap.hx, ci->ap.hy, 0, (ci->Height / 2), CB_PASTE);
}
VOID RefreshAnalogClock(VOID)
{
GetCurrSysTime();
RestoreDisplay();
SaveDisplay();
if (ci->ShowSec)
{
DrawTimeI(ci->ap.hx, ci->ap.hy, ci->apn.HourPen);
DrawTimeI(ci->ap.mx, ci->ap.my, ci->apn.MinPen);
DrawTimeI(ci->ap.sx, ci->ap.sy, ci->apn.SecPen);
}
if (gd->NewTime)
{
DrawTimeI(ci->ap.hx, ci->ap.hy, ci->apn.HourPen);
DrawTimeI(ci->ap.mx, ci->ap.my, ci->apn.MinPen);
gd->NewTime = FALSE;
}
}
WORD DeleteAnalogClock(VOID)
{
ci->Top = gd->ClockWindow->TopEdge;
ci->Left = gd->ClockWindow->LeftEdge;
if (gd->VScreen) UnlockPubScreen(NULL, gd->VScreen);
if (gd->SaveBM) FreeBitMap(gd->SaveBM);
if (gd->ClockGadget) RemoveGadget(gd->ClockWindow, gd->ClockGadget);
// if (gd->TextFont) CloseFont(gd->TextFont);
if (gd->ClockWindow) ClearMenuStrip(gd->ClockWindow);
if (gd->MainMenu) FreeMenus(gd->MainMenu);
if (gd->VisualInfo) FreeVisualInfo(gd->VisualInfo);
if (gd->ClockWindow) CloseWindow(gd->ClockWindow);
gd->VScreen = NULL;
gd->ClockGadget = NULL;
gd->VisualInfo = NULL;
gd->MainMenu = NULL;
// gd->TextFont = NULL;
gd->ClockWindow = NULL;
return NOERROR;
}
/* End Of File */